﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace ImageRenderControl
{
    public class LineShape : Shape
    {
        public PointF StartPoint { get; set; }
        public PointF EndPoint { get; set; }
        // 图像坐标属性
        public PointF StartPointImage { get; private set; }
        public PointF EndPointImage { get; private set; }

        public Pen Pen { get; set; }
        public float Rotation { get; private set; } = 0f;

        public const float RotationDelta = 1f;
        private const float HANDLE_SIZE = 8f;
        private const float MIN_LENGTH = 10f;

        // 缓存变换矩阵
        private Matrix _rotationMatrix;
        private bool _matrixDirty = true;

        public Matrix RotationMatrix
        {
            get
            {
                if (_matrixDirty || _rotationMatrix == null)
                {
                    _rotationMatrix?.Dispose();
                    _rotationMatrix = new Matrix();

                    // 修改为以起始点为旋转中心
                    PointF rotationCenter = StartPoint;

                    _rotationMatrix.Translate(rotationCenter.X, rotationCenter.Y);
                    _rotationMatrix.Rotate(Rotation);
                    _rotationMatrix.Translate(-rotationCenter.X, -rotationCenter.Y);
                    _matrixDirty = false;
                }
                return _rotationMatrix;
            }
        }

        // 获取旋转中心点（覆盖基类方法）
        public override PointF GetRotationCenter()
        {
            return StartPoint;  // 以起始点为旋转中心
        }

        // 仅使用Overlay坐标创建直线
        public LineShape(PointF startPoint, PointF endPoint, Pen pen = null)
        {
            StartPoint = startPoint;
            EndPoint = endPoint;
            Pen = pen ?? new Pen(Color.Red, 2);

            // 初始化图像坐标为默认值，需要后续调用UpdateImageCoordinates方法设置正确值
            StartPointImage = new PointF(0, 0);
            EndPointImage = new PointF(0, 0);
        }

        // 同时使用Overlay坐标和图像坐标创建直线
        public LineShape(PointF startPoint, PointF endPoint, PointF startPointImage, PointF endPointImage, Pen pen = null)
        {
            StartPoint = startPoint;
            EndPoint = endPoint;
            StartPointImage = startPointImage;
            EndPointImage = endPointImage;
            Pen = pen ?? new Pen(Color.Red, 2);
        }

        // 获取中点
        public PointF CenterPoint
        {
            get
            {
                return new PointF(
                    (StartPoint.X + EndPoint.X) / 2f,
                    (StartPoint.Y + EndPoint.Y) / 2f
                );
            }
        }

        // 获取长度
        public float Length
        {
            get
            {
                return (float)Math.Sqrt(
                    Math.Pow(EndPoint.X - StartPoint.X, 2) +
                    Math.Pow(EndPoint.Y - StartPoint.Y, 2)
                );
            }
        }

        public enum HandleType { Start, End, Center }

        public Dictionary<HandleType, PointF> GetHandleCenters()
        {
            Dictionary<HandleType, PointF> handles = new Dictionary<HandleType, PointF>();

            // 获取起点、终点和中心点句柄
            handles[HandleType.Start] = StartPoint;
            handles[HandleType.End] = EndPoint;
            handles[HandleType.Center] = CenterPoint;

            // 如果有旋转，应用旋转变换
            if (Rotation != 0)
            {
                PointF[] points = new PointF[] {
                    handles[HandleType.Start],
                    handles[HandleType.End],
                    handles[HandleType.Center]
                };

                RotationMatrix.TransformPoints(points);

                handles[HandleType.Start] = points[0];
                handles[HandleType.End] = points[1];
                handles[HandleType.Center] = points[2];
            }

            return handles;
        }

        // 获取图像坐标系中的所有关键点
        public PointF[] GetImageCoordinatePoints()
        {
            return new PointF[] { StartPointImage, EndPointImage };
        }

        // 获取Overlay坐标系中的所有关键点
        public PointF[] GetOverlayCoordinatePoints()
        {
            return new PointF[] { StartPoint, EndPoint };
        }

        public override void AdjustRotation(float angleDelta, Func<PointF, PointF> overlayToImageTransform)
        {
            Rotation = (Rotation + angleDelta) % 360;
            if (Rotation < 0) Rotation += 360;
            _matrixDirty = true;

            // 在旋转后更新图像坐标
            if (overlayToImageTransform != null)
            {
                UpdateImageCoordinates(overlayToImageTransform);
            }
        }

        // 调整大小的实现
        public override void AdjustSize(float scaleFactor, Func<PointF, PointF> overlayToImageTransform)
        {
            // 以起始点为不动点，调整终点
            PointF vectorToEnd = new PointF(EndPoint.X - StartPoint.X, EndPoint.Y - StartPoint.Y);

            // 应用缩放
            vectorToEnd.X *= scaleFactor;
            vectorToEnd.Y *= scaleFactor;

            // 计算新的终点
            EndPoint = new PointF(StartPoint.X + vectorToEnd.X, StartPoint.Y + vectorToEnd.Y);

            _matrixDirty = true;

            // 更新图像坐标
            if (overlayToImageTransform != null)
            {
                UpdateImageCoordinates(overlayToImageTransform);
            }
        }

        public void UpdateFromResizing(HandleType handleType, PointF newPosition, Func<PointF, PointF> overlayToImageTransform = null)
        {
            // 如果有旋转，需要先将新位置转换到未旋转的状态
            if (Rotation != 0)
            {
                using (Matrix inverse = RotationMatrix.Clone())
                {
                    inverse.Invert();
                    PointF[] pts = new PointF[] { newPosition };
                    inverse.TransformPoints(pts);
                    newPosition = pts[0];
                }
            }

            // 根据不同控制点更新线段
            switch (handleType)
            {
                case HandleType.Start:
                    StartPoint = newPosition;
                    break;

                case HandleType.End:
                    EndPoint = newPosition;
                    break;

                case HandleType.Center:
                    // 移动中心点将移动整条线
                    PointF oldCenter = CenterPoint;
                    float dx = newPosition.X - oldCenter.X;
                    float dy = newPosition.Y - oldCenter.Y;

                    StartPoint = new PointF(StartPoint.X + dx, StartPoint.Y + dy);
                    EndPoint = new PointF(EndPoint.X + dx, EndPoint.Y + dy);
                    break;
            }

            _matrixDirty = true;

            // 更新图像坐标
            if (overlayToImageTransform != null)
            {
                UpdateImageCoordinates(overlayToImageTransform);
            }
        }

        public override void Draw(Graphics g)
        {
            // 保存图形状态
            GraphicsState state = g.Save();

            try
            {
                g.MultiplyTransform(RotationMatrix);

                using (Pen drawPen = IsSelected ? new Pen(Color.Blue, Pen.Width) : (Pen)Pen.Clone())
                {
                    g.DrawLine(drawPen, StartPoint, EndPoint);
                }
            }
            finally
            {
                // 恢复图形状态
                g.Restore(state);
            }

            if (IsSelected)
            {
                DrawHandles(g);
            }
        }

        private void DrawHandles(Graphics g)
        {
            var handles = GetHandleCenters();

            using (Brush fillBrush = new SolidBrush(Color.Yellow))
            using (Pen borderPen = new Pen(Color.Black, 1))
            {
                foreach (var handle in handles)
                {
                    RectangleF handleRect = new RectangleF(
                        handle.Value.X - HANDLE_SIZE / 2,
                        handle.Value.Y - HANDLE_SIZE / 2,
                        HANDLE_SIZE, HANDLE_SIZE);

                    g.FillRectangle(fillBrush, handleRect);
                    g.DrawRectangle(borderPen, handleRect.X, handleRect.Y, handleRect.Width, handleRect.Height);
                }
            }
        }

        public override bool Contains(Point p)
        {
            using (GraphicsPath path = new GraphicsPath())
            {
                // 添加线段路径
                path.AddLine(StartPoint, EndPoint);

                // 应用旋转变换
                path.Transform(RotationMatrix);

                // 使用较宽的测试画笔进行点击检测
                using (Pen testPen = new Pen(Color.Black, 5))
                {
                    return path.IsOutlineVisible(p, testPen);
                }
            }
        }

        public override void Move(float dx, float dy, Func<PointF, PointF> overlayToImageTransform)
        {
            if (IsSelected)
            {
                StartPoint = new PointF(StartPoint.X + dx, StartPoint.Y + dy);
                EndPoint = new PointF(EndPoint.X + dx, EndPoint.Y + dy);
                _matrixDirty = true;

                // 更新图像坐标
                if (overlayToImageTransform != null)
                {
                    UpdateImageCoordinates(overlayToImageTransform);
                }
            }
        }

        public void Dispose()
        {
            _rotationMatrix?.Dispose();
            Pen?.Dispose();
        }

        public override void UpdateImageCoordinates(Func<PointF, PointF> overlayToImageTransform)
        {
            if (overlayToImageTransform == null) return;

            // 转换起点和终点坐标
            StartPointImage = overlayToImageTransform(StartPoint);
            EndPointImage = overlayToImageTransform(EndPoint);
        }
    }
}
